package com.cosina.game.llk;

import java.util.LinkedList;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.cosina.game.llk.engine.BlankRoute;
import com.cosina.game.llk.engine.Chart;
import com.cosina.game.llk.engine.ConnectiveInfo;
import com.cosina.game.llk.engine.Direction;
import com.cosina.game.llk.engine.DirectionPath;
import com.cosina.game.llk.engine.Tile;

public class LLKView extends View {
	
	private int span = 5;
	private int xStart;
	private int yStart;

	private Tile selectTile;
	private Chart chart;
	
	public Chart getChart(){
		return chart;
	}
	Paint paintForHint = new Paint();
	{
		paintForHint.setColor(Color.BLUE);
		paintForHint.setStrokeWidth(2);
		paintForHint.setStyle(Paint.Style.STROKE);
	}
	Paint paintForPic = new Paint();
	Paint paintForSelect = new Paint();
	{
		paintForSelect.setColor(Color.RED);
		paintForSelect.setStrokeWidth(2);
		paintForSelect.setStyle(Paint.Style.STROKE);
	}
	Paint paintForPath = new Paint();
	{
		paintForPath.setColor(Color.RED);
		paintForPath.setStrokeWidth(3);
	}
	Paint paintForDismissing = new Paint();
	{
		paintForDismissing.setAlpha(80);
	}
	//320 430 //320 370
	public LLKView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		canvas.drawColor(ThemeManager.getCurrentTheme().getBackgroundColor());
		int width = getWidth();
		int height = getHeight();
		
		int sideLength = Math.min(width, height) - 2 * span;

		xStart = (width - sideLength) / 2;
		yStart = (height - sideLength) / 2;
		
		for (int yIndex = 1; yIndex < chart.ySize -1; yIndex++) {
			for (int xIndex = 1; xIndex < chart.xSize -1; xIndex++) {
				try{
					Bitmap bitmap = ThemeManager.getImage(chart.get(xIndex,yIndex).getImage());
					if(null != bitmap)
						canvas.drawBitmap(bitmap, xStart + (xIndex - 1) * ThemeManager.EACH_SIZE, yStart+ (yIndex -1)*ThemeManager.EACH_SIZE, paintForPic);
				}catch(Exception ex){
					
				}
			}
		}
		
		if(null != selectTile){
			canvas.drawRect(xStart + (selectTile.x -1) * ThemeManager.EACH_SIZE, 
							yStart+ (selectTile.y - 1) *ThemeManager.EACH_SIZE, 
							xStart + (selectTile.x)* ThemeManager.EACH_SIZE, 
							yStart+ (selectTile.y)*ThemeManager.EACH_SIZE, 
							paintForSelect);
		}
		for(BlankRoute eachRoute : routes){
			for(DirectionPath each : eachRoute.getpath()){
				Tile eachTile = each.getTile();
				int xPoint = xStart + (eachTile.x -1) * ThemeManager.EACH_SIZE + ThemeManager.EACH_SIZE/2;
				int yPoint = yStart + (eachTile.y -1) * ThemeManager.EACH_SIZE + ThemeManager.EACH_SIZE/2;
				
				for(Direction eachDirection : each.getDirection()){
					canvas.drawLine(xPoint, 
							yPoint,
							xPoint + eachDirection.padding(true, ThemeManager.EACH_SIZE), 
							yPoint + eachDirection.padding(false, ThemeManager.EACH_SIZE), paintForPath);
				}
			}
		}
		
		if(null != hint){
			boolean blank = false;
			
			for(Tile tile : hint){
				if(tile.isBlank()){
					blank = true;
				}
			}
			if(blank == false){
				for(Tile tile : hint){
					canvas.drawRect(xStart + (tile.x -1) * ThemeManager.EACH_SIZE, 
							yStart+ (tile.y - 1) *ThemeManager.EACH_SIZE, 
							xStart + (tile.x)* ThemeManager.EACH_SIZE, 
							yStart+ (tile.y)*ThemeManager.EACH_SIZE, 
							paintForSelect);
				}
			}
		}
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		int xPicIndex = (int)((event.getX() - xStart)/ThemeManager.EACH_SIZE) + 1;
		int yPicIndex = (int)((event.getY() - yStart)/ThemeManager.EACH_SIZE) + 1;
		if(xPicIndex >= chart.xSize || xPicIndex< 0 || yPicIndex >= chart.ySize || yPicIndex < 0)
			return true;
		Tile touchTile = chart.get(xPicIndex, yPicIndex);
		if(touchTile.isBlank() == false){
			handlerTileSelect(touchTile);
		}
		return true;
	}
	
	
	public void setChart(Chart chart) {
		this.chart = chart;
	}
	
	private LinkedList<BlankRoute> routes = new LinkedList<BlankRoute>();
	
	public Runnable hintRunable = new Runnable(){
		public void run(){
			try{
				hint = null;
				LLKView.this.postInvalidate();
			}catch(Exception ex){
				Log.e("cosina1985", ex.toString());
			}
		}
	};
	
	public Runnable runable = new Runnable(){
		public void run(){
			try{
				BlankRoute blankRoute = routes.removeFirst();
				blankRoute.start.dismiss();
				blankRoute.end.dismiss();
				if(blankRoute.start == selectTile || blankRoute.end == selectTile)
					selectTile = null;
				if(chart.isAllBlank()){
					AlertDialog.Builder builder = new AlertDialog.Builder(LLKView.this.getContext());
					builder.setTitle("You win!!!");
					builder.setMessage("click button for new game");
					builder.setCancelable(false);
					builder.setNegativeButton(R.string.new_game_menu_item, new DialogInterface.OnClickListener(){

						@Override
						public void onClick(DialogInterface dialog, int which) {
							LinkLink linklink = (LinkLink)LLKView.this.getContext();
							linklink.resetContent();
						}});
					builder.create().show();
				}
				else
					LLKView.this.postInvalidate();
			}catch(Exception ex){
				Log.e("cosina1985", ex.toString());
			}
		}
	};
	
	private void handlerTileSelect(Tile newTile){
		if(selectTile == null)
			selectTile =  newTile;
		else{
			if(selectTile == newTile)
				return;
			else{
				if(selectTile.getImage() == newTile.getImage()){
					ConnectiveInfo  ci = chart.connectvie(selectTile, newTile);
					if(ci.getResult()){
						selectTile = null;
						routes.add(ci.getRoute().dismissing());
						LLKView.this.postDelayed(runable, 150);
					}else{
						return;
					}
				}else{
					selectTile = newTile;
				}
			}
			
		}
		invalidate();
	}

	private Tile[] hint;
	public void showHint(Tile[] hint) {
		this.hint = hint;
		LLKView.this.postDelayed(hintRunable, 1000);
		invalidate();
	}
}
